<template>
  <div class="image">
    <div
      ref="canvas"
      class="zrender"
      @mousewheel="mousewheel"
      @mousedown="mousedown"
      @mousemove="mousemove"
      @mouseup="mouseup"
      @dblclick="dblclick"
    ></div>
  </div>
</template>

<script>
// import "zrender/src/canvas/canvas";
import { init, Image } from "zrender";

export default {
  mounted() {
    initPara();
    refresh();
  },
  methods: {
    canvas() {
      canvas();
    },
    modifyCenter() {
      modifyCenter();
    },
    mousewheel(e) {
      mousewheel(e);
    },
    mousedown(e) {
      mousedown(e);
    },
    mousemove(e) {
      mousemove(e);
    },
    mouseup(e) {
      mouseup(e);
    },
    dblclick(e) {
      dblclick(e);
    },
  },
};

const canvas = null;

const modifyCenter = () => {
  imageCenter = { x: 200, y: 200 };
  refresh();
};

const mousewheel = (e) => {
  if (e.wheelDelta == 120) {
    if (zoom === maxZoom) {
      return;
    }
    zoom = Math.min(zoom + 1, maxZoom);
    imageCenter.x = e.offsetX + (imageCenter.x - e.offsetX) * 2;
    imageCenter.y = e.offsetY + (imageCenter.y - e.offsetY) * 2;
  } else {
    if (zoom === minZoom) {
      return;
    }
    zoom = Math.max(zoom - 1, minZoom);
    imageCenter.x = e.offsetX + (imageCenter.x - e.offsetX) / 2;
    imageCenter.y = e.offsetY + (imageCenter.y - e.offsetY) / 2;
  }
  refresh();
};

let down = false;
let startPointer = { x: 0, y: 0 };
let startImageCenter = { x: 0, y: 0 };
const mousedown = (e) => {
  down = true;
  startPointer = { x: e.clientX, y: e.clientY };
  startImageCenter = { x: imageCenter.x, y: imageCenter.y };
};
const mousemove = (e) => {
  if (down) {
    imageCenter.x = e.clientX - (startPointer.x - startImageCenter.x);
    imageCenter.y = e.clientY - (startPointer.y - startImageCenter.y);

    refresh();
  }
};
const mouseup = () => {
  down = false;
};
const dblclick = (e) => {
  if (zoom === maxZoom) {
    return;
  }
  zoom = Math.min(zoom + 1, maxZoom);
  imageCenter.x = e.offsetX + (imageCenter.x - e.offsetX) * 2;
  imageCenter.y = e.offsetY + (imageCenter.y - e.offsetY) * 2;

  refresh();
};

const images = {};
const allImages = {};
/**
 * 获取瓦片图片
 */
const getImage = (center, tile, zoom) => {
  console.log(56756788);
  const id = `${zoom}_${tile.nx}_${tile.ny}`;
  if (!allImages[id]) {
    allImages[id] = new Image({
      id,
      style: {
        opacity: 1,
        image: `/C:/Users/86159/Desktop/resoult/baidumap/tiles/${zoom}/tile-${tile.nx}_${tile.ny}.png`,
        x: center.x + tile.x,
        y: center.y + tile.y,
        width: 256,
        height: 256,
      },
    });
  } else {
    allImages[id].attr({
      style: {
        opacity: 1,
        x: center.x + tile.x,
        y: center.y + tile.y,
      },
    });
  }
  return allImages[id];
};

/**
 * 获取瓦片
 */
const getTiles = () => {
  // 图像移动后，图像中心与画布中心相差瓦片数量
  let tileDiff = {
    nx: Math.floor((canvasCenter.x - imageCenter.x) / 256),
    ny: -Math.floor((canvasCenter.y - imageCenter.y) / 256),
  };

  // 瓦片编号、相对中心点坐标
  let xTiles = [];
  for (
    let nx = -tileCount.nx + tileDiff.nx;
    nx <= tileCount.nx + tileDiff.nx;
    nx++
  ) {
    let yTiles = [];
    for (
      let ny = -tileCount.ny - 2 + tileDiff.ny;
      ny <= tileCount.ny + tileDiff.ny;
      ny++
    ) {
      yTiles.push({
        nx,
        ny,
        x: nx * 256 + (imageCenter.x - canvasCenter.x),
        y: ny * 256 * -1 - 256 + (imageCenter.y - canvasCenter.y),
      });
    }
    xTiles.push(yTiles);
  }
  let topTiles = xTiles.splice(0, Math.floor(xTiles.length / 2));
  xTiles = [...topTiles.reverse(), ...xTiles];
  let tiles = [];
  xTiles.forEach((yTiles) => {
    let topTiles = yTiles.splice(0, Math.floor(yTiles.length / 2));
    tiles.push(...topTiles.reverse());
    tiles.push(...yTiles);
  });

  return tiles;
};

/**
 * 刷新瓦片图片
 */
const refresh = () => {
  console.log(1);
  let tiles = getTiles();
  console.log(2);
  // 渲染瓦片图片
  tiles.map((tile) => {
    const id = `${zoom}_${tile.nx}_${tile.ny}`;
    if (images[id]) {
      images[id].attr({
        style: {
          x: canvasCenter.x + tile.x,
          y: canvasCenter.y + tile.y,
        },
      });
    } else {
      console.log(3);
      images[id] = getImage(canvasCenter, tile, zoom);
      zr.add(images[id]);
    }
  });
  Object.keys(images).forEach((key) => {
    if (!tiles.some((tile) => `${zoom}_${tile.nx}_${tile.ny}` === key)) {
      zr.remove(images[key]);
      delete images[key];
    }
  });
};

let width = 0;
let height = 0;

let zoom = 8;
let maxZoom = 8;
let minZoom = 4;

let imageCenter = { x: 0, y: 0 };
let canvasCenter = { x: 0, y: 0 };

let tileCount = { nx: 0, ny: 0 };

let zr;

/**
 * 初始化参数
 */
const initPara = () => {
  zr = init(canvas.value);

  width = zr.getWidth();
  height = zr.getHeight();

  // 图像中心点实际位置
  imageCenter = {
    x: Math.round(width / 2),
    y: Math.round(height / 2),
  };
  // 画布中心点
  canvasCenter = {
    x: Math.round(width / 2),
    y: Math.round(height / 2),
  };
  // 瓦片数量
  tileCount = {
    nx: Math.floor(canvasCenter.x / 256) + 1,
    ny: Math.floor(canvasCenter.y / 256),
  };
};
</script>

<style>
.image {
  height: 100%;
}
.zrender {
  width: 100%;
  height: 100%;
}
</style>